
package com.freeme.cameraplugin.posemode.ui;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

public class RotataTextView extends TextView implements Rotatable {

    private static final int ANIMATION_SPEED = 270; // 270 deg/sec

    private int mCurrentDegree = 0; // [0, 359]
    private int mStartDegree = 0;
    private int mTargetDegree = 0;

    private boolean mClockwise = false, mEnableAnimation = true;

    private long mAnimationStartTime = 0;
    private long mAnimationEndTime = 0;
    private static final int MSG_ROTATE = 0;
    private static final int MSG_ROTATE_DELAY_MS = 10;
    public static final boolean IS_SUPPORT_ROTABLE = false;

    @SuppressLint("HandlerLeak")
    private Handler mHander = new Handler() {

        @SuppressLint("HandlerLeak")
        @Override
        public void handleMessage(Message msg) {
            int what = msg.what;
            switch (what) {
                case MSG_ROTATE:
                    startRotation();
                    break;
                default:
                    break;
            }
        }

    };

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @SuppressLint("NewApi")
    private void startRotation() {
        if (mCurrentDegree != mTargetDegree) {
            long time = AnimationUtils.currentAnimationTimeMillis();
            if (time < mAnimationEndTime) {
                int deltaTime = (int) (time - mAnimationStartTime);
                int degree = mStartDegree + ANIMATION_SPEED * (mClockwise ? deltaTime : -deltaTime)
                        / 1000;
                degree = degree >= 0 ? degree % 360 : degree % 360 + 360;
                mCurrentDegree = degree;
                mHander.sendEmptyMessageDelayed(MSG_ROTATE, MSG_ROTATE_DELAY_MS);
            } else {
                mCurrentDegree = mTargetDegree;
                mHander.removeMessages(MSG_ROTATE);
            }
        }
        this.setRotation(-mCurrentDegree);
    }

    public RotataTextView(Context context) {
        super(context);
    }

    public RotataTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RotataTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setOrientation(int degree, boolean animation) {
        if (!IS_SUPPORT_ROTABLE) {
            return;
        }
        mEnableAnimation = animation;
        // make sure in the range of [0, 359]
        degree = degree >= 0 ? degree % 360 : degree % 360 + 360;
        if (degree == mTargetDegree) return;

        mTargetDegree = degree;
        if (mEnableAnimation) {
            mStartDegree = mCurrentDegree;
            mAnimationStartTime = AnimationUtils.currentAnimationTimeMillis();

            int diff = mTargetDegree - mCurrentDegree;
            diff = diff >= 0 ? diff : 360 + diff; // make it in range [0, 359]

            // Make it in range [-179, 180]. That's the shorted distance between
            // the
            // two angles
            diff = diff > 180 ? diff - 360 : diff;

            mClockwise = diff >= 0;
            mAnimationEndTime = mAnimationStartTime + Math.abs(diff) * 1000 / ANIMATION_SPEED;
        } else {
            mCurrentDegree = mTargetDegree;
        }

        startRotation();
    }
}
